package com.example.persistence;

import java.io.File;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;

import twitter4j.auth.AccessToken;
import android.app.Application;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.os.Build;
import android.telephony.TelephonyManager;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.WindowManager;

import com.example.R;
import com.example.entity.BookmarkList;
import com.example.entity.Capture;
import com.example.entity.CaptureList;
import com.example.entity.Const;
import com.example.module.downloader.ExtendedImageDownloader;
import com.example.util.FileUtil;
import com.facebook.Session;
import com.nostra13.universalimageloader.cache.disc.naming.Md5FileNameGenerator;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
import com.nostra13.universalimageloader.core.assist.QueueProcessingType;

public class MyApplication extends Application {
	
	private static final String TAG = "MyApplication";
	private String deviceId;
	private String phoneNumber;
	private String packageName;
	private String versionName;
	private int versionCode;
	private String appName;
	private int deviceWidth, deviceHeight;
	
	private HashMap<DataType, Object> dataMap = null;
	private BookmarkList bookmarkList = new BookmarkList();
	private CaptureList captureList = new CaptureList();
	private AccessToken twitterAccessToken;
	private String facebookAccessToken;
	private Session facebookSession;
	
	
	enum DataType {
		BOOKMARK_LIST, TWITTER_TOKEN, FACEBOOK_TOKEN, FACEBOOK_SESSION
	}
	
	@Override
	public void onCreate() {
		Log.e(TAG, "onCreate");
		
		DisplayMetrics displayMetrics = new DisplayMetrics();
		((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getMetrics(displayMetrics);
		deviceWidth = displayMetrics.widthPixels;
		deviceHeight = displayMetrics.heightPixels;
		
		TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
		deviceId = telephonyManager.getDeviceId();
		phoneNumber = telephonyManager.getLine1Number();
		appName = getString(R.string.app_name);
		packageName = getPackageName();
		try {
			PackageInfo packageInfo = getPackageManager().getPackageInfo(packageName, 0);
			versionName = packageInfo.versionName;
			versionCode = packageInfo.versionCode;
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		Log.i("MyApplication onCreate", "deviceId=" + deviceId + " phoneNumber=" + phoneNumber);
		Log.i("MyApplication onCreate", "deviceWidth=" + deviceWidth + " deviceHeight=" + deviceHeight);
		Log.i("MyApplication onCreate", "appName=" + appName + " packageName=" + packageName);
		Log.i("MyApplication onCreate", "versionName=" + versionName + " versionCode=" + versionCode);
		
		ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext())
			.threadPriority(Thread.NORM_PRIORITY - 2)
			.memoryCacheSize(Const.IMAGE_MEMORY_CACHE_SIZE)
			.denyCacheImageMultipleSizesInMemory()
			.discCacheFileNameGenerator(new Md5FileNameGenerator())
			.imageDownloader(new ExtendedImageDownloader(getApplicationContext()))
			.tasksProcessingOrder(QueueProcessingType.LIFO)
			.enableLogging() // Not necessary in common
			.build();
	
		// Initialize ImageLoader with configuration.
		ImageLoader.getInstance().init(config);
		
		super.onCreate();
	}
	
	@Override
	public void onTerminate() {
		Log.e(TAG, "onTerminate");
		saveData();
		super.onTerminate();
	}

	public int getSdkVersion() {
		return Build.VERSION.SDK_INT;
	}
	public String getSdkVersionString() {
		return Build.VERSION.SDK;
	}
	public String getAppId() {
		return packageName;
	}
	public String getDeviceId() {
		return deviceId;
	}
	public String getPhoneNumber() {
		return phoneNumber;
	}
	public String getVersionName() {
		return versionName;
	}
	public int getVersionCode() {
		return versionCode;
	}
	public String getAppName() {
		return appName;
	}
	public int getDeviceWidth() {
		return deviceWidth;
	}
	public int getDeviceHeight() {
		return deviceHeight;
	}
	
	public void loadData() {
		Log.e(TAG, "loadData");
		
		Object object = FileUtil.readObjectFromFile(getApplicationContext(), Const.USER_DATA_FILE);
		if (object != null && object instanceof HashMap)
			dataMap = (HashMap<DataType, Object>) object;	
		else
			dataMap = new HashMap<DataType, Object>();
		
		for (DataType dataType : DataType.values()) {
			Log.e(TAG, "loadData "  +dataType + "=" + dataMap.get(dataType));
			
			Object data = dataMap.get(dataType);
			
			if (DataType.BOOKMARK_LIST == dataType) {
				if (data != null) {
					bookmarkList = (BookmarkList) dataMap.get(dataType);
				}
				else {
					bookmarkList = new BookmarkList();
					setBookmarkList(bookmarkList);						
				}
			}
			else if (DataType.TWITTER_TOKEN == dataType) {
				if (data != null) {
					twitterAccessToken = (AccessToken) dataMap.get(dataType);	
				}
			}
			else if (DataType.FACEBOOK_TOKEN == dataType) {
				if (data != null) {
					facebookAccessToken = (String) dataMap.get(dataType);	
				}
			}
			else if (DataType.FACEBOOK_SESSION == dataType) {
				if (data != null) {
					facebookSession = (Session) dataMap.get(dataType);	
				}
			}
		}
		
		try {
			List<String> fileList = FileUtil.getFileList(getCapturePath(), false);
			if (fileList != null) {
				for (String file : fileList) {
					Capture capture = new Capture(FileUtil.ANDROID_FILE_PREFIX+ file, FileUtil.getTimestampFromFileName(file));
					
					String thumbnailFileName = FileUtil.getThumbnailFileName(file);
					File thumbnailFile = new File(thumbnailFileName);
					if (thumbnailFile.exists() && thumbnailFile.isFile())
						capture.setThumbnail(FileUtil.ANDROID_FILE_PREFIX + thumbnailFileName);
					
					captureList.add(capture);
				}
					
				Collections.reverse(captureList);	
			}
			
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public String getCapturePath() {
		return Const.EXTERNAL_ROOT_PATH + "/Capture/"; 
	}
	
	public String getCaptureThumbnailPath() {
		return Const.EXTERNAL_ROOT_PATH + "/Capture/Thumb/"; 
	}
	
	protected void saveData() {
		Log.e(TAG, "saveData");
		
		for (DataType dataType : dataMap.keySet()) {
			Log.e(TAG, "saveData "  +dataType + "=" + dataMap.get(dataType));
		}
		
		FileUtil.writeObjectToFile(this, dataMap, Const.USER_DATA_FILE);
	}

	public BookmarkList getBookmarkList() {
		return bookmarkList;
	}
	public void setBookmarkList(BookmarkList bookmarkList) {
		this.bookmarkList = bookmarkList;
		dataMap.put(DataType.BOOKMARK_LIST, this.bookmarkList);
	}
	
	public CaptureList getCaptureList() {
		return captureList;
	}
	
	public AccessToken getTwitterAccessToken() {
		return twitterAccessToken;
	}
	public void setTwitterAccessToken(AccessToken twitterAccessToken) {
		this.twitterAccessToken = twitterAccessToken;
		dataMap.put(DataType.TWITTER_TOKEN, this.twitterAccessToken);
	}

	public String getFacebookAccessToken() {
		return facebookAccessToken;
	}
	public void setFacebookAccessToken(String facebookAccessToken) {
		this.facebookAccessToken = facebookAccessToken;
		dataMap.put(DataType.FACEBOOK_TOKEN, this.facebookAccessToken);
	}

	public Session getFacebookSession() {
		return facebookSession;
	}
	public void setFacebookSession(Session facebookSession) {
		this.facebookSession = facebookSession;
		dataMap.put(DataType.FACEBOOK_SESSION, this.facebookSession);
	}
}
